package com.thssh.ui.lsn03.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.DiscretePathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.thssh.ui.utils.UiUtils;


/**
 * @author zhangyugehu
 * @version V1.0
 * @date 2017/09/08
 * email: zhangyugehu@163.com
 */

public class PaintHelpView extends View {

    private int dp10;
    private int dp20;
    private int dp30;
    private int dp50;
    private int dp100;
    private int dp200;
    private int dp300;
    private int dp400;

    private boolean isStrokeCapMode = true;
    private boolean isStrokeJoinMode;
    private boolean isPathEffectMode;

    private boolean paintAntiAlias;
    private boolean isRandomPath;

    private int paintStyleType = 2;
    private int strokeJoinType;
    private int strokeCapType;
    private int pathEffectType;

    private int paintWidth = 80;

    public PaintHelpView(Context context) {
        this(context, null);
    }

    public PaintHelpView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PaintHelpView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initDPSizes();
    }

    private void initDPSizes() {
        dp10 = UiUtils.dp2px(10);
        dp20 = UiUtils.dp2px(20);
        dp30 = UiUtils.dp2px(30);
        dp50 = UiUtils.dp2px(50);
        dp100 = UiUtils.dp2px(100);
        dp200 = UiUtils.dp2px(200);
        dp300 = UiUtils.dp2px(300);
        dp400 = UiUtils.dp2px(400);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int suggestWidth = MeasureSpec.getSize(widthMeasureSpec);
        int suggestHeight = MeasureSpec.getSize(heightMeasureSpec);
        int maxHeight = UiUtils.dp2px(200);

        setMeasuredDimension(suggestWidth, maxHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        // 抗锯齿
        paint.setAntiAlias(paintAntiAlias);
        // 设置颜色
        paint.setColor(Color.RED);
        // 画笔样式
        setPaintStyle(paint);
        // 设置透明度 [0..255]
        paint.setAlpha(200);
        // 笔头宽度(粗细)
        paint.setStrokeWidth(paintWidth);

        // 画笔的倾斜度
        paint.setStrokeMiter(45);
        // 设置图像是否使用抖动处理(绘制出来的图像会更加平滑和饱满，图像更加清晰，有一定性能影响)
        // paint.setDither(true);

        if(isStrokeCapMode) {
            // 设置笔帽
            setPaintStrokeCap(paint);
            canvas.drawLine(dp100, dp50, dp300, dp50, paint);
            canvas.drawLine(dp300, dp50, dp100, dp200, paint);
        }else if(isStrokeJoinMode){
            Path path = getPath();
            setPaintStrokeJoin(paint);
            canvas.drawPath(path, paint);
        }else if(isPathEffectMode){
            Path path = getPath();
            setPaintPathEffect(paint);
            canvas.drawPath(path, paint);
        }
    }

    private void setPaintPathEffect(Paint paint) {
        switch (pathEffectType){
            case 0:
                // 虚线效果
                paint.setPathEffect(new DashPathEffect(new float[]{15, 20, 15, 15}, 0));
                break;
            case 1:
                paint.setPathEffect(new DiscretePathEffect(10, 10));
                break;
            case 2:
                // 在连接处替换成一个半径为20 的圆弧
                paint.setPathEffect(new CornerPathEffect(20));
                break;
            case 3:
                paint.setPathEffect(new ComposePathEffect(new DiscretePathEffect(10, 10), new CornerPathEffect(20)));
                break;
            default:
                paint.setPathEffect(new DashPathEffect(new float[]{15, 20, 15, 15}, 0));
                break;
        }
    }

    private void setPaintStrokeJoin(Paint paint) {
        switch (strokeJoinType){
            case 0:
                paint.setStrokeJoin(Paint.Join.BEVEL);
                break;
            case 1:
                paint.setStrokeJoin(Paint.Join.ROUND);
                break;
            case 2:
                paint.setStrokeJoin(Paint.Join.MITER);
                break;
            default:
                paint.setStrokeJoin(Paint.Join.BEVEL);
                break;
        }
    }

    private void setPaintStrokeCap(Paint paint) {
        switch (strokeCapType){
            case 0:
                paint.setStrokeCap(Paint.Cap.BUTT);
                break;
            case 1:
                paint.setStrokeCap(Paint.Cap.ROUND);
                break;
            case 2:
                paint.setStrokeCap(Paint.Cap.SQUARE);
                break;
            default:
                paint.setStrokeCap(Paint.Cap.BUTT);
                break;
        }
    }

    private void setPaintStyle(Paint paint) {
        switch (paintStyleType){
            case 0:
                paint.setStyle(Paint.Style.FILL);
                break;
            case 1:
                paint.setStyle(Paint.Style.FILL_AND_STROKE);
                break;
            case 2:
                paint.setStyle(Paint.Style.STROKE);
                break;
            default:
                paint.setStyle(Paint.Style.FILL);
                break;
        }
    }

    private void resetAllFlag() {
        isStrokeCapMode = false;
        isStrokeJoinMode = false;
        isPathEffectMode = false;
    }

    private Path getPath() {
        if(isRandomPath){
            return getRandomPath(50);
        }
        Path path = new Path();
        path.moveTo(dp100, dp50);
        path.lineTo(dp300, dp50);
        path.lineTo(dp100, dp200);
        return path;
    }

    private Path getRandomPath(int count) {
        Path path = new Path();
        for(int i = 0; i < count; i ++){
            float x = i * 35;
            float y = (float) (Math.random() * UiUtils.dp2px(100));
            if(i == 0){
                path.moveTo(0, 0);
            }else {
                path.lineTo(x, y);
            }
        }
        return path;
    }

    /**
     *
     * @param type
     * 0: Paint.Style.FILL
     * 1: Paint.Style.FILL_AND_STROKE
     * 2: Paint.Style.STROKE
     */
    public void setPaintStyle(int type){
        this.paintStyleType = type;
        invalidate();
    }

    /**
     *
     * @param type
     * 0: Paint.Cap.BUTT
     * 1: Paint.Cap.ROUND
     * 2: Paint.Cap.SQUARE
     */
    public void setStrokeCapType(int type) {
        resetAllFlag();
        isStrokeCapMode = true;
        this.strokeCapType = type;
        invalidate();
    }

    /**
     *
     * 0: Paint.Join.BEVEL
     * 1: Paint.Join.ROUND
     * 2: Paint.Join.MITER
     */
    public void setStrokeJoinType(int type) {
        resetAllFlag();
        isStrokeJoinMode = true;
        this.strokeJoinType = type;
        invalidate();
    }

    public void setPaintAntiAlias(boolean paintAntiAlias) {
        this.paintAntiAlias = paintAntiAlias;
        invalidate();
    }

    public void setPaintPathEffectType(int type){
        resetAllFlag();
        isPathEffectMode = true;
        pathEffectType = type;
        invalidate();
    }

    public void setPaintWidth(int width) {
        paintWidth = width;
        invalidate();
    }

    public void setRandomPath(boolean flag) {
        isRandomPath = flag;
        invalidate();
    }

    public int getPaintWidth() {
        return paintWidth;
    }
}
